import 'dart:io';
import 'dart:math';
import 'dart:convert';
import 'dart:async';

abstract class SocketListener {
  void onOpen() {}
  void onMessage(dynamic msg) {}
  void onClose(int? code, String? reason) {}
}

class P2PSocket {
  String? _url;
  WebSocket? _socket;
  SocketListener? _listener;
  Timer? _timer;

  set listener(listener) {
    _listener = listener;
  }

  //开始连接
  void connect(String url) async {
    try {
      _url = url;
      //自签名验证连接
      _socket = await _connectForSelfSignedCert(_url);
      //打开连接回调
      _listener!.onOpen();
      //监听Socket消息
      _socket!.listen((data) {
        if (_listener != null) _listener!.onMessage(data);
      }, onDone: () {
        if (_timer != null) _timer!.cancel();
        if (_listener != null) {
          _listener!.onClose(_socket!.closeCode, _socket!.closeReason);
        }
      });
      _sendHeartPackage();
    } catch (e) {
      if (_listener != null) _listener!.onClose(500, e.toString());
    }
  }

  _sendHeartPackage() {
    _timer = Timer.periodic(const Duration(seconds: 10), (timer) {
      var request = {};
      request["method"] = "heartPackage";
      request["data"] = {};
      send(jsonEncode(request));
    });
  }

  //发送数据
  send(data) {
    if (_socket != null) {
      _socket!.add(data);
    }
  }

  //关闭socket
  close() {
    if (_timer != null) _timer!.cancel();
    _listener = null;
    if (_socket != null) _socket!.close();
  }
}

Future<WebSocket> _connectForSelfSignedCert(url) async {
  try {
    //随机数
    Random r = Random();
    //生成key
    String key = base64.encode(List<int>.generate(8, (_) => r.nextInt(255)));
    HttpClient client = HttpClient(context: SecurityContext());
    //证书强行被信任
    client.badCertificateCallback =
        (X509Certificate cert, String host, int port) {
       print('P2PSocket: 允许自签名证书 => $host:$port. ');
      //返回true强行被信任
      return true;
    };

    //发起请求
    HttpClientRequest request = await client.getUrl(Uri.parse(url));
    //标识该HTTP请求是一个协议升级请求
    request.headers.add('Connection', 'Upgrade');
    //协议升级为WebSocket协议
    request.headers.add('Upgrade', 'websocket');
    //客户端支持WebSocket的版本
    request.headers.add('Sec-WebSocket-Version', '13');
    //客户端采用base64编码的24位随机字符序列
    request.headers.add('Sec-WebSocket-Key', key.toLowerCase());
    // request.headers.add(TOKEN,  Global.navKey.currentContext.read<AuthModel>().token);

    //关闭请求
    HttpClientResponse response = await request.close();
    //分离出Socket
    Socket socket = await response.detachSocket();
    //通过一个已升级的Socket创建WebSocket
    var webSocket = WebSocket.fromUpgradedSocket(
      socket,
      protocol: 'signaling',
      serverSide: false,
    );
    //返回webSocket
    return webSocket;
  } catch (e) {
    rethrow;
  }
}
